
#include <cstdio>
#include <string>
#include <iostream>
#include <iomanip>

#include "packet.pb.h"

using namespace fekcab;


void	testFillPacket( Packet& pkt )
{

	pkt.set_sid( 4321 );

	pkt.set_type( Packet::REQUEST );

	pkt.set_op( Packet::PING );

	Packet::Item*	item_p = NULL;
	
	item_p = pkt.add_item();
	item_p->set_table( "test table" );
	item_p->set_key( "key001" );
	item_p->set_value( "value001" );

	item_p = pkt.add_item();
	item_p->set_kpin( "key pin" );
	item_p->set_key( "key002" );
	item_p->set_value( "value002" );
	
	item_p = pkt.add_item();
	item_p->set_table( "test table" );
	item_p->set_kpin( "key pin" );
	item_p->set_key( "key003" );

	char	buf[32];
	sprintf(buf, "value003" );
	buf[1] = '\0';
	buf[3] = '\0';
	buf[5] = '\0';

	item_p->set_value( buf, 9 );
}

void	testParsePacket( Packet& pkt )
{
	std::cout << "Packet Data : \n";

	std::cout << "    sid : " << pkt.sid()
			  << "   type : " << pkt.type()
			  << "     op : " << pkt.op()
			  << "  reqid : " << pkt.reqid();

	std::cout << "  limit : " << pkt.limit() << std::endl;

	std::cout << "   item ( count=" << pkt.item_size() << " ) : \n";
	for ( int i=0; i<pkt.item_size(); i++ ) {
		const Packet::Item&	item = pkt.item( i );	

		std::cout << "       #" << i+1 << " table : '" << item.table() << "' (size=" << item.table().size() << ")\n";
		std::cout << "       #" << i+1 << "  kpin : '" << item.kpin() << "' (size=" << item.kpin().size() << ")\n";
		std::cout << "       #" << i+1 << "   key : '" << item.key() << "' (size=" << item.key().size() << ")\n";
		std::cout << "       #" << i+1 << " value : '" << item.value() << "' (size=" << item.value().size() << ")\n";

		std::cout << "             ";
		const std::string&	v = item.value();
		for (size_t k=0; k<v.size(); k++) {
			std::cout << std::hex << std::setiosflags(std::ios::uppercase) << std::setfill('0') << std::setw(2) << static_cast< int >(v[k]) << std::dec << " ";
		}
		std::cout << std::endl;
	}
}


int	main(void)
{
	GOOGLE_PROTOBUF_VERIFY_VERSION;

	Packet	pkt_in;

	testFillPacket( pkt_in );

	std::string	serialized;

	if ( !pkt_in.SerializeToString( &serialized ) ) {
		std::cerr << "fail to serailize to string\n";
		return 1;
	}
	std::cout << "size of serialized string = " << serialized.size() << std::endl;
	
	// parse 

	Packet	pkt_out;
	if ( !pkt_out.ParseFromString( serialized ) ) {
		std::cerr << "fail to unserialized from string\n";
		return 2;
	}

	testParsePacket( pkt_out );


	// Optional:  Delete all global objects allocated by libprotobuf.
    google::protobuf::ShutdownProtobufLibrary();

	return 0;
}

